package com.pub.exception;

import java.sql.SQLException;

import org.springframework.jdbc.CannotGetJdbcConnectionException;

import com.util.StringUtils;

/**
 * 
 * <p>
 * 功能描述:异常工具类
 * </p>
 * 
 * @author <a href="mailto: zhuyoulong@gtss.com.cn">zhuyoulong</a>
 * @create_date 2008-10-27
 * @version $ Revision: 1.0
 */
public final class ExceptionUtils {
	public static final String lineSeparator = System
			.getProperty("line.separator");

	/**
	 * 
	 * <p>
	 * 功能描述：该类不需要实例化
	 * </p>
	 * 
	 * @constructor 方法
	 */
	private ExceptionUtils() {
	}

	/**
	 * 
	 * <p>
	 * 功能描述：格式化输出一个错误的信息
	 * </p>
	 * 
	 * @param e
	 * @return
	 * @author:zhuyoulong
	 * @update:[日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public static String getMessage(Exception e) {
		String result = null;
		try {
			if (e instanceof SQLException) {
				// ---------------------------------
				// 如果该例外是数据库发生的例外，
				// 则调用parseSQLException来解析例外 java.lang.NumberFormatException
				// ---------------------------------
				result = parseSQLException((SQLException) e);
			} else if (e instanceof java.lang.NullPointerException) {
				result = " 当应用程序试图在需要对象的地方使用 null 时，抛出该异常。  ：NullPointerException";
			}else if (e instanceof org.springframework.jdbc.CannotGetJdbcConnectionException) {
				result = " 服务器端数据库连接不上时，抛出该异常。  ：CannotGetJdbcConnectionException";
			} else if (e instanceof CannotGetJdbcConnectionException) {
				result = " 网络没有连接或网络中断 ：CannotGetJdbcConnectionException";
			} else if (e instanceof java.lang.NumberFormatException) {
				result = " 数字转换异常 ：NumberFormatException";
			} else if (e instanceof java.lang.ClassCastException) {
				result = " 当试图将对象强制转换为不是实例的子类时，抛出该异常  ：ClassCastException";
			} else if (e instanceof java.lang.ClassNotFoundException) {
				result = " 类没找到时，抛出该异常  ：ClassNotFoundException";
			} else if (e instanceof java.lang.IllegalAccessException) {
				result = " 当应用程序试图创建一个实例（而不是数组）、设置或获取一个字段，或者调用一个方法，"
						+ "但当前正在执行的方法无法访问指定类、字段、方法或构造方法的定义时，抛出  ：IllegalAccessException";
			} else if (e instanceof java.lang.IllegalArgumentException) {
				result = " 抛出的异常表明向方法传递了一个不合法或不正确的参数。  ：IllegalArgumentException";
			} else if (e instanceof java.lang.IndexOutOfBoundsException) {
				result = " 指示某排序索引（例如对数组、字符串或向量的排序）超出范围时抛出。  ：IndexOutOfBoundsException";
			} else if (e instanceof java.lang.NoSuchFieldException) {
				result = " 类不包含指定名称的字段时产生的信号(bean中不存在这个属性)。  ：NoSuchFieldException";
			} else if (e instanceof java.lang.NoSuchMethodException) {
				result = " 在类中无法找到某一特定方法时，抛出该异常。  ：NoSuchMethodException";
			} else if (e instanceof java.lang.StringIndexOutOfBoundsException) {
				result = " 此异常由 String 方法抛出，指示索引或者为负，或者超出字符串的大小。对诸如 charAt 的一些方法，"
						+ "当索引等于字符串的大小时，也会抛出该异常。  ：StringIndexOutOfBoundsException";
			} else if (e instanceof java.lang.StringIndexOutOfBoundsException) {
				result = " 此异常由 String 方法抛出，指示索引或者为负，或者超出字符串的大小。"
						+ "对诸如 charAt 的一些方法，当索引等于字符串的大小时，也会抛出该异常。  ：StringIndexOutOfBoundsException";
			} else if (e instanceof java.lang.UnsupportedOperationException) {
				result = "当不支持请求的操作时，抛出该异常 。  ：UnsupportedOperationException";
			}
			else if (e instanceof java.lang.ArrayIndexOutOfBoundsException) {
				result = " 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小，则该索引为非法索引 ：ArrayIndexOutOfBoundsException";
			} else if (e instanceof java.lang.ArrayStoreException) {
				result = " 试图将错误类型的对象存储到一个对象数组时抛出的异常  ：ArrayStoreException";
			} else if (e instanceof java.lang.SecurityException) {
				result = "由安全管理器抛出的异常，指示存在安全侵犯。  ：SecurityException";
			}

			else {
				// ---------------------------------
				// 取得错误信息
				// ---------------------------------
				String message = e.getMessage();
				if (message == null || message.length() == 0) {
					// ---------------------------------
					// 如果错误为空，一般可以认为是空指针例外
					// ---------------------------------
					result = "NullPointerException!";
				} else {
					// ---------------------------------
					// 如果错误信息不为空，则格式化错误信息。
					// ---------------------------------
					result = formatMessage(message);
				}
			}
		} catch (Exception e1) {
			// ---------------------------------
			// 如果这里发生的例外。则什么也不处理
			// ---------------------------------
		}
		return result;
	}

	/**
	 * 
	 * <p>
	 * 功能描述：解释某个数据库错误发生的原因，<br>
	 * 适用于Oracle，这个方法应该抽象出来<br>
	 * </p>
	 * 
	 * @param e
	 * @return
	 * @author:zhuyoulong
	 * @update:[日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public static String parseSQLException(SQLException e) {
		int code = e.getErrorCode();
		String result;
		result = "错误代码为：" + code + "，错误信息为：";
		String message = e.getMessage();
		switch (code) {
		case 1:
			result += "主键重复!";
			break;

		case 2:
			result += "名称重复";
			break;

		case 904:
			result += "无效的SQL标识(列名错误？)";
			break;

		case 911:
			result += "无效的SQL字符";
			break;

		case 942:
			result += "表或者视图不存在";
			break;

		case 1006:
			result += "绑定的变量不存在";
			break;

		case 1400:
			result += "插入值不能为空！" + formatMessage(message);
			break;

		case 2289:
			result += "系列生成器不存在！";
			break;

		case 2292:
			result += "子记录发现，不能被删除！" + formatMessage(message);
			break;

		case 1722:
			result += "无效的数字";
			break;
		case 17004:
			result += "字段类型错误";

		default:
			result += formatMessage(message);
		} // switch (code)
		return result;
	}

	/**
	 * 
	 * <p>
	 * 功能描述：格式化消息，以适合JavaScript显示
	 * </p>
	 * 
	 * @param message
	 * @return
	 * @author:zhuyoulong
	 * @update:[日期YYYY-MM-DD][更改人姓名][变更描述]
	 */

	private static String formatMessage(String message) {
		String result = null;
		try {
			// ---------------------------------
			// 格式化错误信息
			// ---------------------------------
			result = StringUtils.replace(message, lineSeparator, "\\\n");
			result = StringUtils.replace(result, "'", "\\\'");
			result = StringUtils.replace(result, "\"", "\\\"");
			// ---------------------------------
			// 只取前100个信息串
			// ---------------------------------
			result = StringUtils.autoCutHZ(result, 100);
		} catch (Exception e) {
		}
		return result;
	}

}
